package charts; 

import flash.events.Event;
import flash.events.MouseEvent;
import charts.series.Element;
import charts.series.dots.Scat;
import charts.Structs.LineStyleStruct;
import string.Utils;
import flash.geom.Point;
import flash.display.Sprite;
import flash.display.BlendMode;
import charts.series.dots.DefaultDotProperties;


class ScatterLine extends ScatterBase<LineStyleStruct, Element> {
	
	public var stepgraph:Int ;
	inline public static var STEP_HORIZONTAL:Int = 1; // TODO - refactor to enum
	inline public static var STEP_VERTICAL:Int = 2; // TODO - refactor to enum

	public function new( json:Dynamic )
	{
		super();
		//
		// so the mask child can punch a hole through the line
		//
		
		stepgraph = 0;
		this.blendMode = BlendMode.LAYER;
		//
		
		// TODO - change this style to an official typedef Type
		this.style = {
			values			: []
			, width			: 2
			, colour		: '#3030d0'
			, text			: ''		// <-- default not display a key
			, font_size'		: 12
			, stepgraph		: 0
			, axis			: 'left'
		};
		
		// hack: keep this incase the merge kills it, we'll
		// remove the merge later (and this hack)
		var js:Dynamic = json['dot-style'];
		
		Object_helper.merge_2( json, style );
		
		this.default_style = new DefaultDotProperties(
			json['dot-style'], this.style.colour, this.style.axis);
			
		this.style.colour = string.Utils.get_colour( style.colour );
		
		this.line_width = style.width;
		this.colour		= this.style.colour;
		this.key		= style.text;
		this.font_size	= style.font_size;
		//this.circle_size = style['dot-size'];
		
		switch (style.stepgraph) {
			case 'horizontal':
				stepgraph = STEP_HORIZONTAL;
			case 'vertical':
				stepgraph = STEP_VERTICAL;
		}

		this.values = style.values;
		this.add_values();
	}
	

	
	// Draw Points...
	public override function resize( sc:ScreenCoordsBase ): Void {
		
		// move the dots:
		super.resize( sc );
		
		this.graphics.clear();
		this.graphics.lineStyle( this.style.width, this.style.colour );
		
		//if( this.style['line-style'].style != 'solid' )
		//	this.dash_line(sc);
		//else
		this.solid_line(sc);	
	}
	
	//
	// This is cut and paste from LineBase
	//
	public function solid_line( sc:ScreenCoordsBase ): Void {
		
		var first:Bool = true;
		var last_x:Int = 0;
		var last_y:Int = 0;

		var areaClosed:Bool = true;
		var isArea:Bool = false;
		var areaBaseX:Int = Math.NaN;
		var areaBaseY:Int = Math.NaN;
		var areaColour:Int = this.colour;
		var areaAlpha:Float = 0.4;
		var areaStyle:Dynamic = this.style['area-style'];
		if (areaStyle != null)
		{
			isArea = true;
			if (areaStyle.x != null)
			{
				areaBaseX = areaStyle.x;
			}
			if (areaStyle.y != null)
			{
				areaBaseY = areaStyle.y;
			}
			if (areaStyle.colour != null)
			{
				areaColour = string.Utils.get_colour( areaStyle.colour );
			}
			if (areaStyle.alpha != null)
			{
				areaAlpha = areaStyle.alpha;
			}
			if (!Math.isNaN(areaBaseX)) 
			{
				// Convert X Value to screen position
				areaBaseX = sc.get_x_from_val(areaBaseX);
			}
			if (!Math.isNaN(areaBaseY)) 
			{
				// Convert Y Value to screen position
				areaBaseY = sc.get_y_from_val(areaBaseY);  // TODO: Allow for right Y-Axis??
			}
		}
		
		for ( i in 0...this.numChildren) {
			
			var spr:Sprite = cast( this.getChildAt(i), Sprite);
			
			
			//trace("!!");
			//
			// filter out the line masks
			//
			if( Std.is( spr, Element) )
			{
				var e:Element = cast( spr, Element);
				
				trace(e.x);
				
				// tell the Point where it is on the screen
				// we will use this info to place the tooltip
				e.resize( sc );
				if (!e.visible)
				{
					// Creates a gap in the plot and closes out the current area if defined
					if ((isArea) && (i > 0))
					{
						// draw an invisible line back to the base and close the fill
						areaX = Math.isNaN(areaBaseX) ? last_x : areaBaseX;
						areaY = Math.isNaN(areaBaseY) ? last_y : areaBaseY;
						this.graphics.lineStyle( 0, areaColour, 0 );
						this.graphics.lineTo(areaX, areaY);
						this.graphics.endFill();
						areaClosed = true;
					}
					first = true;
				}
				else if( first )
				{
					if (isArea)
					{
						// draw an invisible line from the base to the Point
						var areaX:Int = Math.isNaN(areaBaseX) ? e.x : areaBaseX;
						var areaY:Int = Math.isNaN(areaBaseY) ? e.y : areaBaseY;
						// Begin the fill for the area
						this.graphics.beginFill(areaColour, areaAlpha);
						this.graphics.lineStyle( 0, areaColour, 0 );
						this.graphics.moveTo(areaX, areaY);
						this.graphics.lineTo(e.x, e.y);
						areaClosed = false;
						// change the line style back to normal
						this.graphics.lineStyle( this.style.width, this.style.colour, 1.0 );
					}
					else
					{
						// just move to the Point
						this.graphics.moveTo(e.x, e.y);
					}
					first = false;
				}
				else
				{
					if (this.stepgraph == STEP_HORIZONTAL)
						this.graphics.lineTo(e.x, last_y);
					else if (this.stepgraph == STEP_VERTICAL)
						this.graphics.lineTo(last_x, e.y);
				
					this.graphics.lineTo(e.x, e.y);
				}
				last_x = e.x;
				last_y = e.y;
			}
		}

		// Close out the area if defined
		if (isArea && !areaClosed)
		{
			// draw an invisible line back to the base and close the fill
			areaX = Math.isNaN(areaBaseX) ? last_x : areaBaseX;
			areaY = Math.isNaN(areaBaseY) ? last_y : areaBaseY;
			this.graphics.lineStyle( 0, areaColour, 0 );
			this.graphics.lineTo(areaX, areaY);
			this.graphics.endFill();
		}
	}
}
